package cn.uc.ucgc.community.upgrade.shell;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.uc.ucgc.community.upgrade.AppFiles;
import cn.uc.ucgc.community.upgrade.Constants;
import cn.uc.ucgc.community.upgrade.Task;

/**
 * 脚本扩展管理
 * 
 * @author yuyj@ucweb.com
 * @createDate 2014-1-3
 *
 */
public class ShellMgr {
    private static final Logger logger = LoggerFactory.getLogger(ShellMgr.class);
    private static final ShellMgr instance = new ShellMgr();
    private static final String[] EMPTY_PARAMS = new String[0];
    /*准备阶段：任务*/
    private Task prepareTask;
    /*执行阶段任务列表*/
    private Task exeTask;
    /*修正阶段：任务*/
    private Task reviseTask;

    private ShellMgr() {
    };

    public static ShellMgr getInstance() {
        return instance;
    }

    public void initTask() throws DocumentException {
        //1)解析替换任务
        File replaceFile = new File(AppFiles.confHomeFile, "conf/shell.xml");
        if (!replaceFile.exists()) {
            logger.warn("no shell conf file:{}", replaceFile.getAbsolutePath());
            return;
        }
        //1.1)解析全量任务
        //收集数据
        SAXReader reader = new SAXReader();
        Document dom = reader.read(replaceFile);
        List<?> prepareItems = dom.selectNodes(Constants.SHELL_PREPARE_ITEM_PATH);
        List<ShellJob> prepareJobs = collectShellJobs(prepareItems, "prepare");
        if (!prepareJobs.isEmpty()) {
            prepareTask = new ShellTask(prepareJobs);
        }

        List<?> executeItems = dom.selectNodes(Constants.SHELL_EXECUTE_ITEM_PATH);
        List<ShellJob> exeJobs = collectShellJobs(executeItems, "execute");
        if (!exeJobs.isEmpty()) {
            exeTask = new ShellTask(exeJobs);
        }
        List<?> reviseItems = dom.selectNodes(Constants.SHELL_REVISE_ITEM_PATH);
        List<ShellJob> reviseJobs = collectShellJobs(reviseItems, "revise");
        if (!reviseJobs.isEmpty()) {
            reviseTask = new ShellTask(reviseJobs);
        }
    }

    private List<ShellJob> collectShellJobs(List<?> nodes, String type) {
        List<ShellJob> rstLst = new ArrayList<ShellJob>();
        if (null == nodes || nodes.isEmpty()) {
            logger.warn("no {} shell task", type);
            return rstLst;
        }

        for (Object node : nodes) {
            Element ele = (Element) node;
            String cmdPath = ele.attributeValue(Constants.SHELL_ITEM_CMDPATH);
            if (null == cmdPath || cmdPath.isEmpty()) {
                logger.warn("you must config cmdPath in shell.xml");
                continue;
            }
            //判读对应的文件是否存在
            File shellCmdF = new File(AppFiles.confHomeFile, cmdPath);
            if (!shellCmdF.exists() || shellCmdF.isDirectory()) {
                logger.warn("cmdPath:{} must exist,and is a file", cmdPath);
                continue;
            }
            
            String params = ele.attributeValue(Constants.SHELL_ITEM_CMDPARAMS);
            String[] parArray = EMPTY_PARAMS;
            if (null != params && !params.isEmpty()) {
                //解析参数，英文‘,’号隔开
                parArray = params.split(",");
            }
            //在所有脚本参数前两位：老版本路径，新版本路径
            String[] tmpParArr = new String[parArray.length+2];
            tmpParArr[0] = AppFiles.getOldVerHomePath();
            tmpParArr[1] = AppFiles.getNewVerHomePath();
            System.arraycopy(parArray, 0, tmpParArr, 2, parArray.length);
            ShellJob job = new ShellJob(shellCmdF.getAbsolutePath(), tmpParArr);
            rstLst.add(job);
        }

        return rstLst;
    }

    public Task getPrepareTask() {
        return prepareTask;
    }

    public Task getExeTask() {
        return exeTask;
    }

    public Task getReviseTask() {
        return reviseTask;
    }
}
